package cn.elvea.security;

import cn.elvea.domain.Resource;
import cn.elvea.service.ResourceService;
import cn.elvea.utils.SpringContextHolder;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class ShiroFilterChainManager {
    @Autowired
    ResourceService resourceService;

    private Map<String, String> filterChainDefinitionMap;

    public ShiroFilterChainManager() {
        filterChainDefinitionMap = new LinkedHashMap<>();
    }

    public Map<String, String> getSystemFilterChainDefinitionMap() {
        Map<String, String> sysFilterChainDefinitionMap = new LinkedHashMap<>();
        if (!CollectionUtils.isEmpty(filterChainDefinitionMap)) {
            sysFilterChainDefinitionMap.putAll(filterChainDefinitionMap);
        }

        List<Resource> resourceList = resourceService.findAll();
        if (resourceList != null) {
            for (Resource resource : resourceList) {
                sysFilterChainDefinitionMap.put(resource.getName(), "perms[" + resource.getPermission() + "]");
            }
        }
        return sysFilterChainDefinitionMap;
    }

    public void rebuildShiroFilterChain() {
        DefaultFilterChainManager filterChainManager = getFilterChainManager();

        Map<String, String> chains = getSystemFilterChainDefinitionMap();
        if (!CollectionUtils.isEmpty(chains)) {
            filterChainManager.getFilterChains().clear();

            for (Map.Entry<String, String> entry : chains.entrySet()) {
                String url = entry.getKey();
                String chainDefinition = entry.getValue();
                filterChainManager.createChain(url, chainDefinition);
            }
        }
    }

    public DefaultFilterChainManager getFilterChainManager() {
        return ((DefaultFilterChainManager) ((PathMatchingFilterChainResolver) SpringContextHolder.getBean(AbstractShiroFilter.class).getFilterChainResolver()).getFilterChainManager());
    }

    public void setFilterChainDefinitionMap(Map<String, String> filterChainDefinitionMap) {
        this.filterChainDefinitionMap = filterChainDefinitionMap;
    }

    public Map<String, String> getFilterChainDefinitionMap() {
        return this.filterChainDefinitionMap;
    }
}